#ifndef prs_FrmUnlinkControl_H
#define prs_FrmUnlinkControl_H

#include "prs_Form.h"
#include "prs_FrmUseTemplate.h"
#include "prs_FrmRow.h"
/************
#include "prs_FrmPanelStyle.h"
#include "prs_FrmPanel.h"
#include "prs_FrmImageStyle.h"
#include "prs_FrmImage.h"
#include "prs_FrmStringStyle.h"
#include "prs_FrmString.h"
#include "prs_FrmIntegerStyle.h"
#include "prs_FrmInteger.h"
#include "prs_FrmDoubleStyle.h"
#include "prs_FrmDouble.h"
#include "prs_FrmDateStyle.h"
#include "prs_FrmDate.h"
#include "prs_FrmButtonStyle.h"
#include "prs_FrmButton.h"
#include "prs_FrmLineStyle.h"
#include "prs_FrmLine.h"
#include "prs_FrmParaStyle.h"
#include "prs_FrmPara.h"
#include "prs_FrmParaEditStyle.h"
#include "prs_FrmParaEdit.h"
#include "prs_FrmColStyle.h"
#include "prs_FrmCol.h"
#include "prs_FrmRowStyle.h"
#include "prs_FrmRow.h"
#include "prs_FrmTableStyle.h"
#include "prs_FrmTable.h"
#include "prs_FrmSplitterStyle.h"
#include "prs_FrmSplitter.h"
#include "prs_FrmFrameStyle.h"
#include "prs_FrmFrame.h"
#include "prs_FrmPageControlStyle.h"
#include "prs_FrmPageControl.h"
#include "prs_FrmScinPanel.h"
#include "prs_Form.h"
********************/
namespace prs {

///////////////////////////////////////////////////////////////////////////////

struct TFrmUnlinkControl 
:public svl::IVisitor<TNodeForm>
,public svl::IVisitor<TNodeUseTemplate>
,public svl::IVisitor<TNodeUseTemplateBody>
,public svl::IVisitor<TFrmControlsValue>

,public svl::IVisitor<TNodeFrmPanel>
,public svl::IVisitor<TNodeFrmString>
,public svl::IVisitor<TNodeFrmInteger>
,public svl::IVisitor<TNodeFrmDouble>
,public svl::IVisitor<TNodeFrmDate>
,public svl::IVisitor<TNodeFrmImage>
,public svl::IVisitor<TNodeFrmButton>
,public svl::IVisitor<TNodeFrmLine>
,public svl::IVisitor<TNodeFrmPara>
,public svl::IVisitor<TNodeFrmParaEdit>

,public svl::IVisitor<TNodeFrmCol>

,public svl::IVisitor<TNodeFrmRow>
,public svl::IVisitor<TNodeFrmRowCaption>
,public svl::IVisitor<TNodeFrmRowChildren>
,public svl::IVisitor<TNodeFrmRowExpand>

,public svl::IVisitor<TNodeFrmTable>
,public svl::IVisitor<TNodeFrmTableCaption>
,public svl::IVisitor<TNodeFrmTableGrid>

,public svl::IVisitor<TNodeFrmVSplitter>
,public svl::IVisitor<TNodeFrmHSplitter>

,public svl::IVisitor<TNodeFrmFrame>
,public svl::IVisitor<TNodeFrmFrameClient>

,public svl::IVisitor<TNodeFrmPageButton>
,public svl::IVisitor<TNodeFrmPageControl>
,public svl::IVisitor<TNodeFrmPage>

,public svl::IVisitor<TNodeFrmScinPanel>
{
  void Visit(TNodeForm &Node) { Node.AcceptChildren(*this);}
  //
  void Visit(TNodeUseTemplate      &Node) { Node.AcceptChildren(*this);}
  void Visit(TNodeUseTemplateBody  &Node) { Node.AcceptChildren(*this);}
  void Visit(TFrmControlsValue     &Node) { Node.AcceptChildren(*this);}
  //
  void Visit(TNodeFrmPanel    &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmString   &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmInteger  &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmDouble   &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmDate     &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmImage    &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmButton   &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmLine     &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmPara     &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmParaEdit &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmCol      &Node) { unlinkControl(Node);}

  ///////////////////////////////
  void Visit(TNodeFrmRow &Node) {
    frm::control::TRow *P = Node.Control; 
    if (P) { 
      P->BeforeDeleteRow();
    }
    unlinkControl(Node);
  }
  void Visit(TNodeFrmRowCaption  &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmRowChildren &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmRowExpand   &Node) { unlinkControl(Node);}
  /////////////////////////////////////////////////////////////

  void Visit(TNodeFrmTable        &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmTableCaption &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmTableGrid    &Node) { unlinkControl(Node);}

  void Visit(TNodeFrmVSplitter &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmHSplitter &Node) { unlinkControl(Node);}

  void Visit(TNodeFrmFrame       &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmFrameClient &Node) { unlinkControl(Node);}

  void Visit(TNodeFrmPageButton  &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmPageControl &Node) { unlinkControl(Node);}
  void Visit(TNodeFrmPage        &Node) { unlinkControl(Node);}

  void Visit(TNodeFrmScinPanel &Node) { unlinkControl(Node);}

private:
  template<class T> void unlinkControl(T &Node) {
    frm::control::TPanel *Control = Node.Control;
    if (!Control) {
      return;
    }
    frm::TComponent *Parent = Control->GetParent();
    if (!Parent) {
      return;
    }
    destructor(Control);
    Parent->DeleteChild(Control);
  }
  void destructor(frm::control::TPanel *Control) {
    for (int N = 0; N < Control->GetChildrenCount(); N++) {
      destructor( dynamic_cast<frm::control::TPanel*>(&Control->GetChild(N)) );
    }
    Control->destructor();
  }
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
}

#endif
